/* 
 * File:   time.hpp
 * Author: yuri
 *
 * Created on February 7, 2011, 12:21 AM
 */

#ifndef POSIX_WRAPPERS_TIME_HPP_____
#define POSIX_WRAPPERS_TIME_HPP_____

#include "config.hpp"
#include <time.h>

// *****************************************************************************
// * Begin PosixWrap namespace
// *****************************************************************************
BEGIN_PSX_NAMESPACE

/**
 * Class TimeSpec is wrapper for timespec type
 */
class TimeSpec
{
  public:
        explicit TimeSpec(time_t sec=0,long nsec=0);
        explicit TimeSpec(const ::timespec& v);

        TimeSpec& setSec(time_t value);
        time_t getSec() const;

        TimeSpec& setNsec(long value);
        long getNsec() const;

        const TimeSpec& operator=(const ::timespec& v);

        ::timespec& getTimeSpec();
        const ::timespec& getTimeSpec() const;

    friend bool operator==(const TimeSpec& t1, const TimeSpec& t2);
    friend bool operator!=(const TimeSpec& t1, const TimeSpec& t2);
    friend bool operator>(const TimeSpec& t1, const TimeSpec& t2);
    friend bool operator>=(const TimeSpec& t1, const TimeSpec& t2);
    friend bool operator<(const TimeSpec& t1, const TimeSpec& t2);
    friend bool operator<=(const TimeSpec& t1, const TimeSpec& t2);

    friend bool operator==(const TimeSpec& t1, const ::timespec& t2);
    friend bool operator!=(const TimeSpec& t1, const ::timespec& t2);
    friend bool operator>(const TimeSpec& t1, const ::timespec& t2);
    friend bool operator>=(const TimeSpec& t1, const ::timespec& t2);
    friend bool operator<(const TimeSpec& t1, const ::timespec& t2);
    friend bool operator<=(const TimeSpec& t1, const ::timespec& t2);

    friend bool operator==(const ::timespec& t1, const TimeSpec& t2);
    friend bool operator!=(const ::timespec& t1, const TimeSpec& t2);
    friend bool operator>(const ::timespec& t1, const TimeSpec& t2);
    friend bool operator>=(const ::timespec& t1, const TimeSpec& t2);
    friend bool operator<(const ::timespec& t1, const TimeSpec& t2);
    friend bool operator<=(const ::timespec& t1, const TimeSpec& t2);

  private:
    ::timespec data_;
};

/**
 * compare operators for TimeSpec type
 */
bool operator==(const TimeSpec& t1, const TimeSpec& t2);
bool operator!=(const TimeSpec& t1, const TimeSpec& t2);
bool operator>(const TimeSpec& t1, const TimeSpec& t2);
bool operator>=(const TimeSpec& t1, const TimeSpec& t2);
bool operator<(const TimeSpec& t1, const TimeSpec& t2);
bool operator<=(const TimeSpec& t1, const TimeSpec& t2);

bool operator==(const TimeSpec& t1, const ::timespec& t2);
bool operator!=(const TimeSpec& t1, const ::timespec& t2);
bool operator>(const TimeSpec& t1, const ::timespec& t2);
bool operator>=(const TimeSpec& t1, const ::timespec& t2);
bool operator<(const TimeSpec& t1, const ::timespec& t2);
bool operator<=(const TimeSpec& t1, const ::timespec& t2);

bool operator==(const ::timespec& t1, const TimeSpec& t2);
bool operator!=(const ::timespec& t1, const TimeSpec& t2);
bool operator>(const ::timespec& t1, const TimeSpec& t2);
bool operator>=(const ::timespec& t1, const TimeSpec& t2);
bool operator<(const ::timespec& t1, const TimeSpec& t2);
bool operator<=(const ::timespec& t1, const TimeSpec& t2);

/**
 * compare operators for timespec type
 */
bool operator==(const ::timespec& t1, const ::timespec& t2);
bool operator!=(const ::timespec& t1, const ::timespec& t2);
bool operator>(const ::timespec& t1, const ::timespec& t2);
bool operator>=(const ::timespec& t1, const ::timespec& t2);
bool operator<(const ::timespec& t1, const ::timespec& t2);
bool operator<=(const ::timespec& t1, const ::timespec& t2);

// *****************************************************************************
// * Inline functions
// *****************************************************************************

// *****************************************************************************
// * Class TimeSpec
// *****************************************************************************
inline TimeSpec::TimeSpec(time_t sec,long nsec)
{
    data_.tv_sec = sec;
    data_.tv_nsec = nsec;
}

inline TimeSpec::TimeSpec(const ::timespec& v)
{
    data_=v;
}

inline TimeSpec& TimeSpec::setSec(time_t value)
{
    data_.tv_sec = value;
    return *this;
}

inline time_t TimeSpec::getSec() const
{
    return data_.tv_sec;
}

inline TimeSpec& TimeSpec::setNsec(long value)
{
    data_.tv_nsec = value;
    return *this;
}

inline long TimeSpec::getNsec() const
{
    return data_.tv_nsec;
}

inline const TimeSpec& TimeSpec::operator=(const ::timespec& v)
{
    data_=v;
    return *this;
}

inline ::timespec& TimeSpec::getTimeSpec()
{
    return data_;
}

inline const ::timespec& TimeSpec::getTimeSpec() const
{
    return data_;
}

// *****************************************************************************
// * functions compare(const ::timespec& t1, const ::timespec& t2)
// *****************************************************************************
inline bool operator==(const ::timespec& t1, const ::timespec& t2)
{
    return t1.tv_sec == t2.tv_sec && t1.tv_nsec == t2.tv_nsec;
}

inline bool operator!=(const ::timespec& t1, const ::timespec& t2)
{
    return t1.tv_sec != t2.tv_sec || t1.tv_nsec != t2.tv_nsec;
}

inline bool operator>(const ::timespec& t1, const ::timespec& t2)
{
    return (t1.tv_sec > t2.tv_sec)? true :
        t1.tv_sec == t2.tv_sec && t1.tv_nsec >  t2.tv_nsec;
}

inline bool operator>=(const ::timespec& t1, const ::timespec& t2)
{
    return (t1.tv_sec > t2.tv_sec)? true :
        t1.tv_sec == t2.tv_sec && t1.tv_nsec >=  t2.tv_nsec;
}

inline bool operator<(const ::timespec& t1, const ::timespec& t2)
{
    return (t1.tv_sec < t2.tv_sec)? true :
        t1.tv_sec == t2.tv_sec && t1.tv_nsec <  t2.tv_nsec;
}

inline bool operator<=(const ::timespec& t1, const ::timespec& t2)
{
    return (t1.tv_sec < t2.tv_sec)? true :
        t1.tv_sec == t2.tv_sec && t1.tv_nsec <=  t2.tv_nsec;
}

// *****************************************************************************
// * functions compare(const TimeSpec& t1, const TimeSpec& t2)
// *****************************************************************************
inline bool operator==(const TimeSpec& t1, const TimeSpec& t2)
{
    return t1.data_ == t2.data_;
}

inline bool operator!=(const TimeSpec& t1, const TimeSpec& t2)
{
    return t1.data_ != t2.data_;
}

inline bool operator>(const TimeSpec& t1, const TimeSpec& t2)
{
    return t1.data_ > t2.data_;
}

inline bool operator>=(const TimeSpec& t1, const TimeSpec& t2)
{
    return t1.data_ >= t2.data_;
}

inline bool operator<(const TimeSpec& t1, const TimeSpec& t2)
{
    return t1.data_ < t2.data_;
}

inline bool operator<=(const TimeSpec& t1, const TimeSpec& t2)
{
    return t1.data_ <= t2.data_;
}

// *****************************************************************************
// * functions compare(const TimeSpec& t1, const ::timespec& t2)
// *****************************************************************************
inline bool operator==(const TimeSpec& t1, const ::timespec& t2)
{
    return t1.data_ == t2;
}
inline bool operator!=(const TimeSpec& t1, const ::timespec& t2)
{
    return t1.data_ != t2;
}
inline bool operator>(const TimeSpec& t1, const ::timespec& t2)
{
    return t1.data_ > t2;
}
inline bool operator>=(const TimeSpec& t1, const ::timespec& t2)
{
    return t1.data_ >= t2;
}
inline bool operator<(const TimeSpec& t1, const ::timespec& t2)
{
    return t1.data_ < t2;
}
inline bool operator<=(const TimeSpec& t1, const ::timespec& t2)
{
    return t1.data_ <= t2;
}

// *****************************************************************************
// * functions compare(const ::timespec& t1, const TimeSpec& t2)
// *****************************************************************************
inline bool operator==(const ::timespec& t1, const TimeSpec& t2)
{
    return t1 == t2.data_;
}

inline bool operator!=(const ::timespec& t1, const TimeSpec& t2)
{
    return t1 != t2.data_;
}

inline bool operator>(const ::timespec& t1, const TimeSpec& t2)
{
    return t1 > t2.data_;
}

inline bool operator>=(const ::timespec& t1, const TimeSpec& t2)
{
    return t1 >= t2.data_;
}

inline bool operator<(const ::timespec& t1, const TimeSpec& t2)
{
    return t1 < t2.data_;
}

inline bool operator<=(const ::timespec& t1, const TimeSpec& t2)
{
    return t1 != t2.data_;
}

// *****************************************************************************
// * End PosixWrap namespace
// *****************************************************************************
END_PSX_NAMESPACE

#endif  //#ifndef POSIX_WRAPPERS_TIME_HPP_____
